﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
using Kaskelot.SP.Model.Client;
using Stockholm.SOA.Kaskelot.WCF.DataContracts;
using Kaskelot.SP.Services.Client.Mapping;
using Kaskelot.SP.Model.Client.Forms;
using Microsoft.SharePoint;
using Kaskelot.SP.Core;
using System.Web;

namespace Kaskelot.SP.Services.Client
{
	[ServiceContract(Namespace = "http://Kaskelot.SP.Services")]
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(MaxItemsInObjectGraph = 2147483647)]
	public class ClientPersonService
	{
		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<PersonSearchResult>> SearchPersoner(string fritext, string typId, string visaInaktiva, string postnummer, string personnummer, string namn, string funktionId, string endastBemannade)
		{
			ClientServiceResult<IEnumerable<PersonSearchResult>> csr = new ClientServiceResult<IEnumerable<PersonSearchResult>>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					PersonSearchParameters parameters = new PersonSearchParameters();

					// För att förhindra att man gör en sökning utan filter (tar för lång tid)
					if (!string.IsNullOrEmpty(typId) ||
						!string.IsNullOrEmpty(fritext) ||
						!string.IsNullOrEmpty(postnummer) ||
						!string.IsNullOrEmpty(personnummer) ||
						!string.IsNullOrEmpty(namn) ||
						funktionId.IsGuid())
					{
					if (!string.IsNullOrEmpty(typId))
						parameters.TypId = new Guid(typId);
					else
						parameters.TypId = null;
					if (!string.IsNullOrEmpty(visaInaktiva))
						parameters.VisaInaktiva = System.Convert.ToBoolean(visaInaktiva);
					if (!string.IsNullOrEmpty(fritext))
						parameters.Fritext = fritext;
					if (!string.IsNullOrEmpty(postnummer))
						parameters.Postnummer = postnummer;
					if (!string.IsNullOrEmpty(personnummer))
						parameters.Personnummer = personnummer;
					if (!string.IsNullOrEmpty(namn))
						parameters.Namn = namn;
					if (funktionId.IsGuid())
						parameters.FunktionId = new Guid(funktionId);
					if (!string.IsNullOrEmpty(endastBemannade))
						parameters.EndastBemannade = System.Convert.ToBoolean(endastBemannade);

					IList<PersonSearchResult> result = svc.SearchPersoner(parameters);

					csr.Data = result.OrderBy(x => x.Namn);
				}
			}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<ClientPerson> GetPerson(string id)
		{
			ClientServiceResult<ClientPerson> csr = new ClientServiceResult<ClientPerson>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					csr.Data = svc.GetPerson(new Guid(id)).ToClientContract();
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientPersonHandelseLogg>> GetPersonHandelseLogg(string id)
		{
			ClientServiceResult<IEnumerable<ClientPersonHandelseLogg>> csr = new ClientServiceResult<IEnumerable<ClientPersonHandelseLogg>>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					var v = svc.GetPersonHandelseLoggByPersonId(new Guid(id)).Select(l => l.ToClientContract()).ToList();

					foreach (ClientPersonHandelseLogg cphl in v)
					{
						cphl.Text = cphl.Text.Length > 65 ? cphl.Text.Substring(0, 60) + " (...)" : cphl.Text;
					}

					csr.Data = v;
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreatePersonHandelseLogg(HandelseLoggForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					PersonHandelseLogg phl = new PersonHandelseLogg()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id,
						Id = Guid.NewGuid()
					};
					phl.UpdateContract(form);
					svc.CreateHandelseLogg(phl);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdatePersonHandelseLogg(HandelseLoggForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					if (form.Id.IsGuid())
					{
						PersonHandelseLogg phl = svc.GetPersonHandelseLogg(new Guid(form.Id));
						phl.UpdateContract(form);
						svc.UpdateHandelseLogg(phl);
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> DeletePersonHandelseLogg(HandelseLoggForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					if (form.Id.IsGuid())
					{
						svc.DeleteHandelseLogg(new Guid(form.Id));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> UpdatePerson(PersonDetailsForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					if (!form.Epost.IsValidEpost())
						throw new ApplicationException("Ej giltig epostadress.");
					if (!form.Personnummer.IsValidPersNr())
						throw new ApplicationException("Ett giltigt personnummer enligt formatet ÅÅÅÅMMDD-XXXX krävs.");
					if (!form.PostNr.IsNullOrEmpty() && !form.PostNr.IsValidPostNr())
						throw new ApplicationException("Ett postnummer enligt formatet 123 45 krävs.");

					Person p = svc.GetPersonByPersonnummer(form.Personnummer);
					if (p != null && (!form.Id.IsGuid() || (form.Id.IsGuid() && p.Id != new Guid(form.Id))))
						throw new ApplicationException("En person med personnummer " + form.Personnummer + " existerar redan.");

					if (form.Id.IsGuid())
					{
						Person person = svc.GetPerson(new Guid(form.Id));
						svc.UpdatePerson(person.UpdateContract(form));
					}
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> CreatePerson(PersonDetailsForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					if (!form.Epost.IsValidEpost())
						throw new ApplicationException("Ej giltig epostadress.");
					if (!form.Personnummer.IsValidPersNr())
						throw new ApplicationException("Ett giltigt personnummer enligt formatet ÅÅÅÅMMDD-XXXX krävs.");
					if (!form.PostNr.IsNullOrEmpty() && !form.PostNr.IsValidPostNr())
						throw new ApplicationException("Ett postnummer enligt formatet 123 45 krävs.");
					if (svc.GetPersonByPersonnummer(form.Personnummer) != null)
						throw new ApplicationException("En person med personnummer " + form.Personnummer + " existerar redan.");

					Person person = new Person()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};
					csr.Data = svc.CreatePerson(person.UpdateContract(form)).ToString();
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> AddKontaktpersonToByggnad(KontaktpersonForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					PersonByggnad pb = new PersonByggnad()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id
					};
					svc.AddKontaktpersonToByggnad(pb.UpdateContract(form));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> RemoveKontaktpersonFromByggnad(KontaktpersonForm form)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					svc.RemoveKontaktpersonFromByggnad(new Guid(form.PersonId), new Guid(form.ByggnadId));
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> AddNewKontaktpersonToByggnad(string ByggnadId, string PersonId)
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					svc.CreatePersonPersonTyp(new Guid(PersonId), PersonTyp.KontaktpersonTypId);

					PersonByggnad pb = new PersonByggnad()
					{
						SkapadAv = SPContext.Current.Web.CurrentUser.Name,
						Skapad = DateTime.Now,
						ValId = ApplicationContext.Current.Val.Id,
						Id = Guid.NewGuid(),
						Andrad = null,
						AndradAv = null,
						ByggnadId = new Guid(ByggnadId),
						PersonId = new Guid(PersonId)
					};

					svc.AddKontaktpersonToByggnad(pb);
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<ClientByggnad>> GetByggnadListByKontaktpersonId(string kontaktpersonId)
		{
			ClientServiceResult<IEnumerable<ClientByggnad>> csr = new ClientServiceResult<IEnumerable<ClientByggnad>>();

			try
			{
				using (PersonService svc = new PersonService())
				{
					csr.Data = svc.GetByggnadListByKontaktpersonId(new Guid(kontaktpersonId)).Select(b => b.ToClientContract());
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<IEnumerable<PersonUppdrag>> GetUppdragByPerson(string id)
		{
			ClientServiceResult<IEnumerable<PersonUppdrag>> csr = new ClientServiceResult<IEnumerable<PersonUppdrag>>();

			try
			{
				using (BemanningService svc = new BemanningService())
				{
					var grupper = svc.GetBemanningGruppByPersonId(new Guid(id));
					var valdistrikt = svc.GetBemanningValdistriktByPersonId(new Guid(id));

					if (grupper != null)
						grupper = grupper.OrderByDescending(g => g.ValDatum).ThenBy(g => g.ValNamn).ThenBy(g => g.GruppNamn);

					if(valdistrikt != null)
						valdistrikt = valdistrikt.OrderByDescending(g => g.ValDatum).ThenBy(g => g.ValNamn).ThenBy(g => g.ValdistriktNamn);

					IList<PersonUppdrag> list = new List<PersonUppdrag>();

					foreach (BemanningGrupp g in grupper)
					{
						list.Add(new PersonUppdrag
						{
							UppdragFunktion = g.FunktionNamn,
							UppdragNamn = g.GruppNamn,
							UppdragVal = g.ValNamn,
							GruppId = g.GruppId.ToString(),
							Current = g.ValId == ApplicationContext.Current.Val.Id
						});
					}

					foreach (BemanningValdistrikt v in valdistrikt)
					{
						list.Add(new PersonUppdrag
						{
							UppdragFunktion = v.FunktionNamn,
							UppdragNamn = v.ValdistriktNamn,
							UppdragVal = v.ValNamn,
							ValdistriktId = v.ValdistriktId.ToString(),
							Current = v.ValId == ApplicationContext.Current.Val.Id
						});
					}

					//csr.Data = list.OrderBy(gubpr => gubpr.UppdragVal).ThenBy(gubpr => gubpr.UppdragNamn);
					csr.Data = list;
				}
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}

		[OperationContract]
		[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
		public ClientServiceResult<string> GetKontaktpersonTypId()
		{
			ClientServiceResult<string> csr = new ClientServiceResult<string>();

			try
			{
				csr.Data = PersonTyp.KontaktpersonTypId.ToString();
			}
			catch (Exception ex)
			{
				csr.ErrorMessage = ex.Message;
				csr.HasError = true;
			}

			return csr;
		}
	}
}
